﻿using AutoMapper;
using B.S.Medical.Api.Read.Application.Command.Register;
using B.S.Medical.Api.Read.DTOS;
using B.S.Medical.Domain.Department;
using B.S.Medical.Domain.Doctor;
using B.S.Medical.Domain.Medical;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Medical.Api.Read.Application.Handler.Register
{
    /// <summary>
    /// 显示挂号业务
    /// </summary>
    public class ShowRegisterHandler : IRequestHandler<ShowRegisterCommand, ApiPageing<RegisterDto>>
    {
        private readonly IBaseRepository<RegisterModel> _registerRepository;
        private readonly IBaseRepository<PatientModel> _patientRepository;
        private readonly IBaseRepository<DoctorModel> _doctorRepository;
        private readonly IBaseRepository<ManageModel> _departmentRepository;
        private readonly IBaseRepository<registrationModel> _registrationRepository;
        private readonly ILogger<ShowRegisterHandler> _logger;
        private readonly IMapper _mapper;

        public ShowRegisterHandler(
            IBaseRepository<RegisterModel> registerRepository,
            IBaseRepository<PatientModel> patientRepository,
            IBaseRepository<DoctorModel> doctorRepository,
            IBaseRepository<ManageModel> departmentRepository,
            IBaseRepository<registrationModel> registrationRepository,
            ILogger<ShowRegisterHandler> logger,
            IMapper mapper)
        {
            _registerRepository = registerRepository;
            _patientRepository = patientRepository;
            _doctorRepository = doctorRepository;
            _departmentRepository = departmentRepository;
            _registrationRepository = registrationRepository;
            _logger = logger;
            _mapper = mapper;
        }

        public async Task<ApiPageing<RegisterDto>> Handle(ShowRegisterCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始查询挂号记录，查询条件：状态={Status}，开始日期={StartDate}，结束日期={EndDate}，诊室={ConsultingRoom}，搜索名称={SearchName}",
                    request.Status, request.StartDate, request.EndDate, request.ConsultingRoom, request.SearchName);

                // 构建联合查询
                var query = from register in _registerRepository.GetAll().Where(r => !r.IsDeleted)
                            join patient in _patientRepository.GetAll().Where(p => !p.IsDeleted) 
                                on register.PatientId equals patient.Id
                            join doctor in _doctorRepository.GetAll().Where(d => !d.IsDeleted) 
                                on register.DoctorId equals doctor.Id
                            join department in _departmentRepository.GetAll().Where(d => !d.IsDeleted) 
                                on doctor.DepartmentId equals department.Id
                            join registration in _registrationRepository.GetAll().Where(r => !r.IsDeleted)
                                on register.registrationId equals registration.Id into regGroup
                            from registration in regGroup.DefaultIfEmpty() // 左连接
                            select new
                            {
                                Register = register,
                                Patient = patient,
                                Doctor = doctor,
                                Department = department,
                                Registration = registration
                            };

                // 应用过滤条件
                if (!string.IsNullOrEmpty(request.Status) && request.Status != "全部")
                {
                    query = query.Where(x => x.Register.Status == request.Status);
                }

                if (request.StartDate.HasValue)
                {
                    query = query.Where(x => x.Register.VisitDate.Date >= request.StartDate.Value.Date);
                }

                if (request.EndDate.HasValue)
                {
                    query = query.Where(x => x.Register.VisitDate.Date <= request.EndDate.Value.Date);
                }

                if (!string.IsNullOrEmpty(request.ConsultingRoom))
                {
                    query = query.Where(x => x.Department.DepartmentName.Contains(request.ConsultingRoom));
                }

                if (!string.IsNullOrEmpty(request.SearchName))
                {
                    query = query.Where(x =>
                        x.Patient.Name.Contains(request.SearchName) ||
                        x.Doctor.DoctorName.Contains(request.SearchName));
                }

                // 获取总记录数
                var totalCount = await query.CountAsync(cancellationToken);

                // 计算总页数
                var totalPage = (int)Math.Ceiling(totalCount / (double)request.PageSize);

                _logger.LogInformation("查询挂号记录, 总记录数: {TotalCount}, 总页数: {TotalPage}", totalCount, totalPage);
                
                // 应用分页并获取数据
                var results = await query
                    .OrderByDescending(x => x.Register.CreateTime)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .Select(x => new RegisterDto
                    {
                        // 基本挂号信息
                        Id = x.Register.Id,                         // 挂号记录ID
                        PatientId = x.Register.PatientId,           // 患者ID
                        PatientName = x.Patient.Name,               // 患者姓名，从患者实体获取
                        
                        // 从患者表获取的信息
                        MedicalCardNumber = x.Patient.IdCard,       // 使用患者身份证作为就诊卡号
                        IdCardNumber = x.Patient.IdCard,            // 身份证号码
                        PhoneNumber = x.Patient.Phone,              // 联系电话

                        // 科室信息
                        DepartmentId = x.Department.Id,             // 科室ID
                        Department = x.Department.DepartmentName,   // 科室名称

                        // 医生信息
                        DoctorId = x.Register.DoctorId,             // 医生ID
                        DoctorName = x.Doctor.DoctorName,           // 医生姓名

                        // 挂号相关信息
                        RegisterType = x.Register.Type,             // 挂号类型
                        RegisterFee = x.Register.Fee,               // 挂号费用
                        RegisterStatus = x.Register.Status,         // 挂号状态
                        RegisterDate = x.Register.VisitDate,        // 就诊日期
                        AppointmentTime = x.Register.AppointmentTime, // 预约时间

                        // 号源信息
                        registrationId = x.Register.registrationId,  // 号源ID
                        slot_number = x.Registration != null ? x.Registration.slot_number : x.Register.slot_number  // 号源序号
                    })
                    .ToListAsync(cancellationToken);

                _logger.LogInformation("成功获取挂号记录, 当前页数据条数: {Count}", results.Count);

                // 构建返回结果
                var apiPageing = new ApiPageing<RegisterDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "获取挂号记录成功",
                    TotaCount = totalCount,
                    TotaPage = totalPage,
                    PageData = results
                };

                return apiPageing;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取挂号记录时发生异常: {Message}", ex.Message);
                return new ApiPageing<RegisterDto>
                {
                    Code = ApiEnum.Error,
                    Msg = $"获取挂号记录失败：{ex.Message}",
                    TotaCount = 0,
                    TotaPage = 0,
                    PageData = new List<RegisterDto>()
                };
            }
        }
    }
}